import { assign } from 'min-dash';

import { MenuMap } from './consts';

import './provider.scss';

export default function PaletteProvider(
  palette,
  create,
  elementFactory,
  handTool,
  lassoTool,
  spaceTool,
  globalConnect,
  translate
) {
  this.create = create;
  this.elementFactory = elementFactory;
  this.handTool = handTool;
  this.lassoTool = lassoTool;
  this.spaceTool = spaceTool;
  this.globalConnect = globalConnect;
  this.translate = translate;

  palette.registerProvider(this);
}

PaletteProvider.$inject = [
  'palette',
  'create',
  'elementFactory',
  'handTool',
  'lassoTool',
  'spaceTool',
  'globalConnect',
  'translate',
];

PaletteProvider.prototype.getPaletteEntries = function (element) {
  const { create, elementFactory, handTool, lassoTool, spaceTool, globalConnect, translate } = this;

  const createSubprocess = (event) => {
    const subProcess = elementFactory.createShape({
      type: 'bpmn:SubProcess',
      x: 0,
      y: 0,
      isExpanded: true,
    });

    const startEvent = elementFactory.createShape({
      type: 'bpmn:StartEvent',
      x: 40,
      y: 82,
      parent: subProcess,
    });

    create.start(event, [subProcess, startEvent], {
      hints: {
        autoSelect: [startEvent],
      },
    });
  };

  const createItem = (type, opts = {}) => {
    const { group, className, title, businessObject: options = {}, action } = {
      ...opts,
      ...(MenuMap[type] || {}),
    };

    const titleStr = title || translate(`Create ${type}`);

    const createShape = () => {
      const shape = elementFactory.createShape(assign({ type: type }, options));
      assign(shape.businessObject, options, { name: titleStr });
      shape.businessObject.di.isExpanded = options.isExpanded;

      return shape;
    };

    const createListener = (event) => {
      create.start(event, createShape());
    };

    const elementAction = action || createListener;

    return {
      group: group,
      className: className,
      title: titleStr,
      action: {
        dragstart: elementAction,
        click: elementAction,
      },
    };
  };

  return {
    'hand-tool': {
      group: 'tools',
      className: 'bpmn-icon-hand-tool',
      title: '抓手工具',
      action: {
        click: function (event) {
          handTool.activateHand(event);
        },
      },
    },
    'lasso-tool': {
      group: 'tools',
      className: 'bpmn-icon-lasso-tool',
      title: '套索工具',
      action: {
        click: function (event) {
          lassoTool.activateSelection(event);
        },
      },
    },
    'space-tool': {
      group: 'tools',
      className: 'bpmn-icon-space-tool',
      title: '调整间隔',
      action: {
        click: function (event) {
          spaceTool.activateSelection(event);
        },
      },
    },
    'global-connect-tool': {
      group: 'tools',
      className: 'bpmn-icon-connection-multi',
      title: '连线工具',
      action: {
        click: function (event) {
          globalConnect.toggle(event);
        },
      },
    },
    'tool-separator': {
      group: 'tools',
      separator: true,
    },

    'create.start-event': createItem('bpmn:StartEvent'),
    'create.end-event': createItem('bpmn:EndEvent'),
    'create.timer-intermediate-event': createItem('bpmn:IntermediateThrowEvent'),
    'create.intermediate-catch-event': createItem('bpmn:IntermediateThrowEvent'),
    'create.user-task': createItem('bpmn:UserTask'),
    'create.service-task': createItem('bpmn:ServiceTask'),
    'create.invoke-task': createItem('bpmn:InvokeTask'),
    'create.script-task': createItem('bpmn:ScriptTask'),
    'create.exclusive-gateway': createItem('bpmn:ExclusiveGateway'),
    'create.parallel-gateway': createItem('bpmn:ParallelGateway'),
    'create.inclusive-gateway': createItem('bpmn:InclusiveGateway'),
    'create.participant': createItem('bpmn:Participant'),
    'create.subprocess-expanded': createItem('bpmn:SubProcess', { action: createSubprocess }),

    'create.group': createItem('bpmn:Group', {
      group: 'collaboration',
      className: 'bpmn-icon-group',
    }),
  };
};
